package com.lframework.jh.push.manage.controller;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lframework.jh.push.core.annotations.security.HasPermission;
import com.lframework.jh.push.core.components.mq.MqProducer;
import com.lframework.jh.push.core.components.redis.RedisHandler;
import com.lframework.jh.push.core.components.resp.InvokeResult;
import com.lframework.jh.push.core.components.resp.InvokeResultBuilder;
import com.lframework.jh.push.core.components.resp.PageResult;
import com.lframework.jh.push.core.constants.MqConstants;
import com.lframework.jh.push.core.exceptions.impl.DefaultClientException;
import com.lframework.jh.push.core.utils.CollectionUtil;
import com.lframework.jh.push.core.utils.PageResultUtil;
import com.lframework.jh.push.core.utils.StringUtil;
import com.lframework.jh.push.manage.bo.notify.GetNotifyDataBo;
import com.lframework.jh.push.manage.bo.notify.QueryNotifyDataBo;
import com.lframework.jh.push.plugin.core.dto.NotifySmsBatchDto;
import com.lframework.jh.push.service.entity.NotifyData;
import com.lframework.jh.push.service.service.NotifyDataService;
import com.lframework.jh.push.service.vo.notify.QueryNotifyDataVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 回调通知
 *
 * @author zmj
 */
@Api(tags = "回调通知")
@Validated
@RestController
@RequestMapping("/notify/data")
public class NotifyDataController {

    @Autowired
    private NotifyDataService notifyDataService;

    @Autowired
    private MqProducer mqProducer;

    @Autowired
    private RedisHandler redisHandler;

    /**
     * 查询列表
     */
    @ApiOperation("查询列表")
    @HasPermission({"notify-data:query"})
    @GetMapping("/query")
    public InvokeResult<PageResult<QueryNotifyDataBo>> query(@Valid QueryNotifyDataVo vo) {

        Wrapper<NotifyData> queryWrapper = Wrappers.lambdaQuery(NotifyData.class)
            .eq(vo.getMchId() != null, NotifyData::getMchId, vo.getMchId())
            .eq(StringUtil.isNotBlank(vo.getBatchNo()), NotifyData::getBatchNo, vo.getBatchNo())
            .like(StringUtil.isNotBlank(vo.getNotifyUrl()), NotifyData::getNotifyUrl,
                vo.getNotifyUrl())
            .ge(vo.getStartTime() != null, NotifyData::getCreateTime, vo.getStartTime())
            .le(vo.getEndTime() != null, NotifyData::getCreateTime, vo.getEndTime())
            .orderByDesc(NotifyData::getCreateTime);

        Page<NotifyData> page = notifyDataService.page(
            new Page<>(vo.getPageIndex(), vo.getPageSize()), queryWrapper);
        PageResult<NotifyData> pageResult = PageResultUtil.convert(page);

        List<NotifyData> datas = pageResult.getDatas();
        List<QueryNotifyDataBo> results = null;

        if (!CollectionUtil.isEmpty(datas)) {
            results = datas.stream().map(QueryNotifyDataBo::new).collect(Collectors.toList());
        }

        return InvokeResultBuilder.success(PageResultUtil.rebuild(pageResult, results));
    }

    /**
     * 查询详情
     */
    @ApiOperation("查询详情")
    @ApiImplicitParam(value = "ID", name = "id", paramType = "query", required = true)
    @HasPermission({"notify-data:query"})
    @GetMapping
    public InvokeResult<GetNotifyDataBo> get(@NotBlank(message = "ID不能为空！") String id) {

        NotifyData notifyData = notifyDataService.getById(id);
        if (notifyData == null) {
            throw new DefaultClientException("通知详情不存在！");
        }

        return InvokeResultBuilder.success(new GetNotifyDataBo(notifyData));
    }

    /**
     * 重试通知
     */
    @ApiOperation("重试通知")
    @ApiImplicitParam(value = "ID", name = "id", paramType = "query", required = true)
    @HasPermission({"notify-data:retry"})
    @PostMapping("/retry")
    public InvokeResult<Void> retry(@NotBlank(message = "ID不能为空！") String id) {

        NotifyData notifyData = notifyDataService.getById(id);
        if (notifyData == null) {
            throw new DefaultClientException("通知详情不存在！");
        }

        // 15分钟内不允许重复通知
        String key = "retry_notify_data:" + notifyData.getId();
        Object flag = redisHandler.get(key);
        if (flag != null) {
            throw new DefaultClientException("15分钟内不允许重复发起通知！");
        }

        redisHandler.set(key, Boolean.TRUE, 15 * 60 * 1000L);

        NotifySmsBatchDto dto = new NotifySmsBatchDto();
        dto.setNotifyId(notifyData.getId());
        mqProducer.sendMessage(MqConstants.QUEUE_NOTIFY_SMS_BATCH, dto);

        return InvokeResultBuilder.success();
    }
}
